﻿using System.Collections.ObjectModel;
using System.Diagnostics;
using Utils;
using System;

namespace StockModel
{
	[DebuggerDisplay("Loaded Day = {_day}. Quotes = {ItemsCount}")]
	[Serializable]
	public class QuotationDailyInfo : IDisposable
	{
		#region Attributes

		private readonly QuotationDailyStatisticsCalculator _dailyStatisticsCalculator;
		private readonly DailyKeyQuotationsCalculator _dailyKeyQuotationsCalculator;

		#endregion

		#region Properties

		public ReadWriteLockedObservableCollection<Quotation> Quotations { get; private set; }
		
		public DailyKeyQuotations DailyKeyQuotations
		{
			get
			{
				return _dailyKeyQuotationsCalculator.DailyKeyQuotations;
			}
		}

		public QuotationDailyStatistics DailyStatistics
		{
			get
			{
				return _dailyStatisticsCalculator.Statistics;
			}
		}
		
		// Used only by the DebuggerDisplayAttribute
		// ReSharper disable UnusedMember.Local
		private int ItemsCount
		{
			get
			{
				int result = this.Quotations.GetReadLock().Count;
				this.Quotations.FreeReadLock();
				return result;
			}
		}
		// ReSharper restore UnusedMember.Local

		#endregion

		#region Public Methods

		public QuotationDailyInfo(DateTime day)
		{
			this.Quotations = new ReadWriteLockedObservableCollection<Quotation>(Properties.Settings.Default.MaxWaitTimeQuotationsWriteAccess);

			_dailyKeyQuotationsCalculator = new DailyKeyQuotationsCalculator(this.Quotations, day);
			_dailyStatisticsCalculator = new QuotationDailyStatisticsCalculator(_dailyKeyQuotationsCalculator.DailyKeyQuotations);
		}

		public void Clear()
		{
			ObservableCollection2<Quotation> quotations = this.Quotations.GetWriteLock();
			try
			{
				quotations.Clear();	
			}
			finally
			{
				this.Quotations.FreeWriteLock();	
			}

			this.DailyKeyQuotations.Clear();
		}
		
		public bool IsLastQuotationClosed()
		{
			bool result;
			ObservableCollection<Quotation> quotations = this.Quotations.GetReadLock();

			if (quotations.Count > 0)
			{
				try
				{
					result = quotations[quotations.Count - 1].Type == QuoteType.Closed;
				}
				finally
				{
					this.Quotations.FreeReadLock();
				}
			}
			else
			{
				result = false;
			}

			return result;
		}

		#endregion

		#region IDisposable

		protected bool Disposed { get; private set; }

		private void Dispose(bool disposing)
		{
			if (!this.Disposed)
			{
				this.InternalDispose(disposing);
			}

			this.Disposed = true;
		}

		protected virtual void InternalDispose(bool disposing)
		{
			if (disposing)
			{
				_dailyKeyQuotationsCalculator.Dispose();
				_dailyStatisticsCalculator.Dispose();
			}

			// Dispose here only unmanaged objects 
			// Don’t use managed objects here because maybe 
			// they have been finalized already
		}

		public void Dispose()
		{
			this.Dispose(true);
			GC.SuppressFinalize(this);
		}

		~QuotationDailyInfo()
		{
			this.Dispose(false);
		}

		#endregion

	}
}
